#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/pem.h>

int sm2_encrypt(const char *pubkey_file, const unsigned char *in, size_t in_len,
                unsigned char **out, size_t *out_len) {
    FILE *fp = fopen(pubkey_file, "r");
    EVP_PKEY *pkey = PEM_read_PUBKEY(fp, NULL, NULL, NULL);
    fclose(fp);
    if (!pkey) return -1;

    EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL);
    if (!ctx) { EVP_PKEY_free(pkey); return -1; }

    if (EVP_PKEY_encrypt_init(ctx) <= 0 ||
        EVP_PKEY_CTX_set_ec_scheme(ctx, NID_sm2) <= 0 ||
        EVP_PKEY_encrypt(ctx, NULL, out_len, in, in_len) <= 0) {
        EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); return -1;
    }

    *out = malloc(*out_len);
    if (EVP_PKEY_encrypt(ctx, *out, out_len, in, in_len) <= 0) {
        free(*out); *out = NULL;
        EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); return -1;
    }

    EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey);
    return 0;
}

int main() {
    const char *msg = "fsl";
    unsigned char *ciphertext = NULL;
    size_t ciphertext_len = 0;

    if (sm2_encrypt("sm2public_key.pem", (unsigned char*)msg, strlen(msg),
                    &ciphertext, &ciphertext_len) == 0) {
        // 输出密文长度（不打印二进制内容，避免乱码）
        printf("SM2 encrypt success, ciphertext length: %zu bytes\n", ciphertext_len);
        free(ciphertext);
    } else {
        fprintf(stderr, "SM2 encrypt failed\n");
        return 1;
    }
    return 0;
}
